package com.gin.kotlin.no_gay_alliance.fragment.main.usercenter

import android.content.DialogInterface
import android.view.Gravity
import android.view.View
import android.widget.CompoundButton
import android.widget.EditText
import androidx.appcompat.widget.PopupMenu
import androidx.recyclerview.widget.GridLayoutManager
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions
import com.gin.kotlin.no_gay_alliance.R
import com.gin.kotlin.no_gay_alliance.activity.TopicListActivity
import com.gin.kotlin.no_gay_alliance.activity.UseItemActivity
import com.gin.kotlin.no_gay_alliance.activity.UserCenterActivity
import com.gin.kotlin.no_gay_alliance.activity.pm.PrivateMessageNewActivity
import com.gin.kotlin.no_gay_alliance.adapter.community.ForumEntryAdapter
import com.gin.kotlin.no_gay_alliance.adapter.user.MedalInUserCenterAdapter
import com.gin.kotlin.no_gay_alliance.adapter.user.OldNameAdapter
import com.gin.kotlin.no_gay_alliance.adapter.user.ReputationAdapter
import com.gin.kotlin.no_gay_alliance.adapter.user.UserBuffAdapter
import com.gin.kotlin.no_gay_alliance.adapter.user.UserHeaderRecyclerViewAdapter
import com.gin.kotlin.no_gay_alliance.adapter.user.UserRemarkAdapter
import com.gin.kotlin.no_gay_alliance.app.App
import com.gin.kotlin.no_gay_alliance.argument.TopicListArgument
import com.gin.kotlin.no_gay_alliance.base.AlertDialogUtils
import com.gin.kotlin.no_gay_alliance.base.ClipboardUtils
import com.gin.kotlin.no_gay_alliance.base.GlideModule.Companion.CROSS_FADE
import com.gin.kotlin.no_gay_alliance.base.InputMethodUtils
import com.gin.kotlin.no_gay_alliance.base.PhotoPreviewUtils
import com.gin.kotlin.no_gay_alliance.base.ViewUtils.Companion.visible
import com.gin.kotlin.no_gay_alliance.callback.RCallback
import com.gin.kotlin.no_gay_alliance.database.dao.BanUserDao
import com.gin.kotlin.no_gay_alliance.database.dao.ReplyHistoryUserDao
import com.gin.kotlin.no_gay_alliance.database.entity.BanUser
import com.gin.kotlin.no_gay_alliance.database.entity.ReplyHistoryUser
import com.gin.kotlin.no_gay_alliance.databinding.FragmentUserCenterTabBaseInfoBinding
import com.gin.kotlin.no_gay_alliance.fragment.topiclist.UserSearchFragment
import com.gin.kotlin.no_gay_alliance.listener.PhotoPreviewLongClickListener
import com.gin.kotlin.no_gay_alliance.model.ItemTypeModel
import com.gin.kotlin.no_gay_alliance.model.UserDetailModel
import com.gin.kotlin.no_gay_alliance.provider.ngaphp.ItemTypeProvider
import com.gin.kotlin.no_gay_alliance.provider.ngaphp.OldNameProvider
import com.gin.kotlin.no_gay_alliance.store.GlobalProperty
import com.gin.kotlin.no_gay_alliance.utils.TimeUtils.Companion.FULL_DATE_TIME_FORMATTER
import com.gin.nga.callback.NgaCallback
import com.gin.nga.enums.NgaPhpApi
import com.gin.nga.enums.param.ItemType
import com.gin.nga.response.base.NgaResponse
import com.gin.nga.response.user.BlockConfig
import com.gin.nga.response.user.Money
import com.gin.nga.response.user.OldName
import com.gin.nga.response.user.TinyUserInfo
import com.gin.nga.utils.NgaUrlUtils
import com.gin.retrofit.utils.JacksonUtils
import retrofit2.Call
import retrofit2.Response

/**
 * 用户中心，用户基础信息：头像，用户ID，用户名,账号状态，用户组，威望，注册时间，发帖数，IP属地，总赞，礼物，被关注数
 * 是否已关注，用户名历史
 * 查询：主题，回复，收藏
 * 操作：私信，道具，拉黑，解除拉黑
 */
class UserCenterTabBaseInfoFragment : AbstractUserCenterTabFragment<FragmentUserCenterTabBaseInfoBinding>, View.OnClickListener, NgaCallback<List<String>>,
    CompoundButton.OnCheckedChangeListener {
    private lateinit var replyHistoryUserDao: ReplyHistoryUserDao
    private lateinit var banUserDao: BanUserDao
    private lateinit var listDataAdapter: UserHeaderRecyclerViewAdapter

    constructor() : super()
    constructor(data: UserDetailModel?) : super(data)

    override fun onCreateView() {
        this.replyHistoryUserDao = App.INSTANCE.database.replyHistoryUserDao()
        this.banUserDao = App.INSTANCE.database.banUserDao()
        val b = this.b ?: return


        val (
            userId, username, regDatetime, accountStatus, postCount,
            group, adminForums, followed, followedCount, ipLocation,
            honor, totalAgreement, giftReceived, userForum, _, usernameChanged,
            reputation, buffs,
            remarks,
            avatars, medalId, prestige,
            signature, money, timestamp) = userDetail
        // 是否为当前账号的用户中心
        val currentUser = userId!! == App.INSTANCE.account.userId

        // 开关布局配置
        run {
            listOf(b.swBlock, b.swBlockMore, b.swFollow).forEach { it.visibility = visible(!currentUser) }
            // 是否已屏蔽（官方）
            b.swBlock.isChecked = App.INSTANCE.blockConfig?.users?.any { it.userId == userId } == true
            // 是否已屏蔽（额外）
            b.swBlockMore.isChecked = banUserDao.get(userId) != null
            b.swFollow.isChecked = followed == true
            b.swReplyHistoryUser.isChecked = replyHistoryUserDao.get(userId) != null
            // 切换操作
            listOf(b.swBlock, b.swBlockMore, b.swFollow, b.swReplyHistoryUser).forEach { it.setOnCheckedChangeListener(this) }
        }


        // 荣誉
        b.tvHonor.visibility = if (honor.isNullOrEmpty()) View.GONE else View.VISIBLE
        b.tvHonor.text = honor?.let { "荣誉 $it" }

        // 头像
        avatars?.also { list ->
            // 显示第一个头像
            Glide.with(requireContext()).load(list[0]).apply(RequestOptions().circleCrop()).error(R.drawable.ic_person_18)
                .transition(DrawableTransitionOptions.withCrossFade(CROSS_FADE)).placeholder(R.drawable.ic_person_18).into(b.ivUserAvatar)

            // 点击预览
            b.ivUserAvatar.setOnClickListener {
                PhotoPreviewUtils.build(requireActivity(), list, listener = PhotoPreviewLongClickListener(requireContext()) { position ->
                    run {
                        val url = list[position]
                        PhotoPreviewLongClickListener.PreviewImage(url, "")
                    }
                }).build().show(b.ivUserAvatar)
            }
        }

        // 用户名和用户ID
        b.tvUsername.text = "$username - $userId"
        // 威望，用户组
        b.tvPrestige.text = "$group 威望 ${prestige?.div(10.0)}"

        //账号状态, 点击提示
        accountStatus?.also { b.tvAccountStatus.text = "[${it.cn}]" }
        // 注册时间
        regDatetime?.also { b.tvRegDateTime.text = getString(R.string.tv_reg_date_time, FULL_DATE_TIME_FORMATTER.format(it)) }
        // 发帖数
        postCount?.also { b.tvPostCount.text = getString(R.string.tv_post_count, it.toString()) }
        //IP属地
        ipLocation?.also { b.tvIpLocation.text = it }


        b.tvBtPrivateMessage.visibility = if (currentUser) View.GONE else View.VISIBLE

        // 点击事件
        listOf(
            b.tvAccountStatus, b.tvUsername, b.tvBtPrivateMessage, b.tvBtGift, b.tvBtTopic, b.tvBtReply,
            b.tvBtFavor, b.tvPrestige, b.tvRegDateTime, b.tvPostCount, b.tvMoreInfo,
        ).forEach { it.setOnClickListener(this) }


        b.tvMoreInfo.text = run {
            val sb = StringBuilder()
            totalAgreement?.also { sb.append("总赞数: ").append(it).append("  ") }
            giftReceived?.also { sb.append("本年获赠礼物: ").append(it).append("  ") }
            followedCount?.also { sb.append("被关注: ").append(it).append("  ") }
            money?.also { sb.append("\n货币: ").append(Money(it).toString()) }
            sb.toString()
        }


        // 其他列表数据

        val groupData = mutableListOf<UserHeaderRecyclerViewAdapter.DataGroup>()
        //备注
        remarks?.takeIf { it.isNotEmpty() }?.also {
            val adapter = UserRemarkAdapter(requireContext(), handler!!, it.toMutableList())
            groupData.add(UserHeaderRecyclerViewAdapter.DataGroup("备注", adapter))
        }
        // 声望
        reputation?.takeIf { it.isNotEmpty() }?.also {
            val adapter = ReputationAdapter(requireContext(), handler!!, it.toMutableList())
            groupData.add(UserHeaderRecyclerViewAdapter.DataGroup("声望", adapter))
        }
        // buff
        buffs?.takeIf { it.isNotEmpty() }?.also {
            val adapter = UserBuffAdapter(requireContext(), handler!!, it.toMutableList())
            groupData.add(UserHeaderRecyclerViewAdapter.DataGroup("BUFF", adapter))
        }
        // 管理版面
        adminForums?.takeIf { it.isNotEmpty() }?.also {
            val data = it.toMutableList()
            data.firstOrNull { f -> f.name == userForum }?.also { f -> f.name = "[个]${f.name}" }
            val adapter = ForumEntryAdapter(requireContext(), handler!!, data)
            groupData.add(UserHeaderRecyclerViewAdapter.DataGroup("管理版面", adapter, GridLayoutManager(requireContext(), 3)))
        }


        this.listDataAdapter = UserHeaderRecyclerViewAdapter(requireContext(), handler!!, groupData)
        b.recyclerView.adapter = listDataAdapter

        // 曾用名
        if (usernameChanged) {
            OldNameProvider.getInstance().enqueue(params = userId, callback = object : RCallback<List<OldName>, Long> {
                override fun onSuccess(data: List<OldName>, ignoreCache: Boolean) {
                    val adapter = OldNameAdapter(requireContext(), handler!!, data.toMutableList())
                    val dataGroup = UserHeaderRecyclerViewAdapter.DataGroup("曾用名", adapter)
                    listDataAdapter.pushData(dataGroup, 0)

                }

                override fun onError(errorMessage: String) {
                    toast("曾用名获取失败: $errorMessage")
                }
            })
        }

        // 徽章
        medalId?.also { id ->
            ItemTypeProvider.getInstance().enqueue(ItemType.MEDAL, id, callback = object : RCallback<List<ItemTypeModel>, List<Pair<Int, Int>>> {
                override fun onSuccess(data: List<ItemTypeModel>, ignoreCache: Boolean) {
                    val adapter = MedalInUserCenterAdapter(requireContext(), handler!!, data.toMutableList())
                    val dataGroup = UserHeaderRecyclerViewAdapter.DataGroup("徽章", adapter, GridLayoutManager(requireContext(), 2))
                    listDataAdapter.pushData(dataGroup)
                }

                override fun onError(errorMessage: String) {
                    toast("徽章信息获取失败: $errorMessage")
                }
            })

        }


    }

    /**
     * Called when a view has been clicked.
     *
     * @param v The view that was clicked.
     */
    override fun onClick(v: View?) {
        val (
            userId, username, regDatetime, accountStatus, postCount,
            group, adminForums, followed, followedCount, ipLocation,
            honor, totalAgreement, giftReceived, userForum, email, usernameChanged,
            reputation, buffs,
            remarks,
            avatars, medalId, prestige, signature, timestamp,
        ) = userDetail

        when (v?.id) {
            // 弹窗复制
            R.id.tv_username, R.id.tv_prestige, R.id.tv_reg_date_time, R.id.tv_post_count, R.id.tv_more_info -> PopupMenu(requireContext(), v).also { menu ->
                menu.inflate(R.menu.copy)
                menu.inflate(R.menu.copy_user)
                menu.setForceShowIcon(true)
                menu.setOnMenuItemClickListener {
                    val text = when (it.itemId) {
                        R.id.mi_copy_link -> NgaUrlUtils.build(GlobalProperty.getInstance().domain, NgaPhpApi.NUKE, Pair("func", "ucp"), Pair("uid", userId.toString()))
                        R.id.mi_copy_code -> "[uid=$userId]$username[/uid]"
                        R.id.mi_copy_username -> username.toString()
                        R.id.mi_copy_user_id -> userId.toString()
                        R.id.mi_copy_at -> if (username?.toIntOrNull() != null) "[@$userId]" else "[@$username]"
                        else -> throw RuntimeException("非法取值")
                    }
                    //复制到剪贴板
                    ClipboardUtils.setText(text, requireContext())
                    toast("已复制")
                    true
                }
                menu.gravity = Gravity.START
                menu.show()
            }
            // 弹窗详情
            R.id.tv_account_status -> AlertDialogUtils.builder(requireContext(), accountStatus?.description, accountStatus?.tip).show()
            // 查询主题
            R.id.tv_bt_topic -> UserSearchFragment.startActivityTopic(requireContext(), userId!!, title = "$username 的主题")
            // 查询回复
            R.id.tv_bt_reply -> UserSearchFragment.startActivityReply(requireContext(), userId!!, title = "$username 的回复")
            // 使用道具
            R.id.tv_bt_gift -> UseItemActivity.start(requireContext(), userId!!)
            // 发起私信
            R.id.tv_bt_private_message -> PrivateMessageNewActivity.start(requireContext(), arrayListOf(username!!))
            // 打开收藏夹
            R.id.tv_bt_favor -> TopicListActivity.startActivity(requireContext(), TopicListArgument(TopicListArgument.Type.FAVOR_FOLDER, authorUid = userId))
        }
    }

    private fun blockConfigSet(config: BlockConfig) = App.INSTANCE.ngaApi.accountApi.blockConfigSet(config).enqueue(this)

    override fun onSuccess(
        call: Call<NgaResponse<List<String>>>,
        response: Response<NgaResponse<List<String>>>,
        body: NgaResponse<List<String>>?,
        data: List<String>?
    ) {
        data?.get(0)?.also { toast(it) }
        handler?.post { (requireActivity() as? UserCenterActivity)?.also { a -> a.refresh() } }
    }

    override fun onError(call: Call<NgaResponse<List<String>>>, response: Response<NgaResponse<List<String>>>, body: NgaResponse<List<String>>?, errorMessage: String) {
        toastLong(errorMessage)
        handler?.post { (requireActivity() as? UserCenterActivity)?.also { a -> a.refresh() } }
    }

    /**
     * 开关切换的操作
     * @param buttonView CompoundButton
     * @param isChecked Boolean
     */
    override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
        val userId = userDetail.userId!!
        val username = userDetail.username!!

        when (buttonView?.id) {
            // 屏蔽（官方）
            R.id.sw_block -> App.INSTANCE.blockConfig?.also { config ->
                if (isChecked)
                    config.users?.add(TinyUserInfo(userId, username))
                else
                    config.users?.removeIf { it.userId == userId }

                blockConfigSet(config)
            }
            // 屏蔽（额外）
            R.id.sw_block_more -> {
                if (isChecked) {
                    b?.swBlockMore?.also { switch ->
                        // 先移除listener
                        switch.setOnCheckedChangeListener(null)
                        switch.isChecked = false

                        // 弹窗输入备注
                        val editText = EditText(requireContext())
                        editText.requestFocus()
                        editText.selectAll()
                        editText.hint = "屏蔽备注(可选)"

                        AlertDialogUtils.builder(requireContext(), "屏蔽备注", contentView = editText, listener = { _, which ->
                            if (which == DialogInterface.BUTTON_POSITIVE) {
                                banUserDao.add(listOf(BanUser(userId = userId, username = username, remark = editText.text.toString())))
                                switch.isChecked = true
                                toast("已屏蔽: $username")
                            }
                        })
                            // 关闭弹窗后恢复 listener
                            .setOnDismissListener { switch.setOnCheckedChangeListener(this) }
                            .show()
                        uiDelayed(200) { InputMethodUtils.show(editText, requireContext()) }
                    }
                } else {
                    banUserDao.del(userId)
                    toast("屏蔽已解除: $username")
                }
            }
            // 关注
            R.id.sw_follow -> if (isChecked)
                App.INSTANCE.ngaApi.followApi.follow(userId).enqueue(this)
            else
                App.INSTANCE.ngaApi.followApi.unfollow(userId).enqueue(this)
            // 观察
            R.id.sw_reply_history_user -> if (isChecked) {
                AlertDialogUtils.builder(requireContext(), title = "观察用户", "你'看到的'该用户的发言将被记录").show()
                replyHistoryUserDao.add(ReplyHistoryUser(userId, username, 0))
            } else {
                replyHistoryUserDao.del(userId)
            }
        }
    }
}